<template>
  <nf-container>
    <nf-crud
      ref="crud"
      :option="option"
      :table-loading="loading"
      :data="data"
      v-model:page="page"
      v-model="form"
      @search-change="searchChange"
      @search-reset="searchReset"
      @selection-change="selectionChange"
      @current-change="currentChange"
      @size-change="sizeChange"
      @refresh-change="onLoad(page, query)"
      @on-load="onLoad"
    >
      <template #processDefinitionName="{ row }">
        <el-link
          v-if="permission.wf_ops_detail"
          style="font-size: 12px"
          type="primary"
          @click="handleDetail(row)"
          >{{ row.processDefinitionName }}</el-link
        >
        <span v-else>{{ row.processDefinitionName }}</span>
      </template>
      <template #menu="{ row }">
        <el-button
          v-if="permission.wf_ops_follow"
          text
          type="primary"
          size="default"
          icon="el-icon-search"
          @click="handleFlow(row)"
        >
          流程图
        </el-button>
        <el-button
          v-if="permission.wf_ops_delete_process"
          text
          type="primary"
          size="default"
          icon="el-icon-delete"
          @click="handleDeleteProcess(row)"
        >
          删除
        </el-button>
      </template>
      <template #menu-left>
        <el-button
          v-if="permission.wf_ops_delete_process"
          type="danger"
          size="default"
          icon="el-icon-delete"
          @click="handleDeleteProcess()"
        >
          删除
        </el-button>
      </template>
    </nf-crud>

    <el-dialog v-model="bpmnVisible" append-to-body destroy-on-close title="流程图">
      <nf-design ref="bpmn" style="height: 500px" :options="bpmnOption"></nf-design>
    </el-dialog>
    <el-drawer
      v-model="detailVisible"
      :title="form.processDefinitionName"
      class="nf-drawer"
      size="60%"
      append-to-body
    >
      <task-detail
        v-if="detailVisible"
        :taskId="form.taskId"
        :processInstanceId="form.processInstanceId"
      ></task-detail>
    </el-drawer>
  </nf-container>
</template>

<script>
import { detail } from '../../api/process/process';
import { processList as getList, deleteProcess } from '../../api/ops/ops';
import { mapGetters } from 'vuex';

import TaskDetail from './detail.vue';
import exForm from '../../mixins/ex-form';

export default {
  mixins: [exForm],
  components: {
    TaskDetail,
  },
  data() {
    return {
      form: {},
      query: {},
      loading: true,
      page: {
        pageSize: 10,
        currentPage: 1,
        total: 0,
      },
      selectionList: [],
      option: {
        size: 'default',
        height: 'auto',
        calcHeight: 30,
        tip: false,
        border: true,
        selection: true,
        dialogType: 'drawer',
        addBtn: false,
        editBtn: false,
        delBtn: false,
        align: 'center',
        searchSize: 'default',
        searchIndex: 3,
        searchIcon: true,
        column: [
          {
            label: '流程名称',
            prop: 'processDefinitionName',
            search: true,
            overHidden: true,
          },
          {
            label: '流程标识',
            prop: 'processDefinitionKey',
            search: true,
            overHidden: true,
          },
          {
            label: '流水号',
            prop: 'serialNumber',
            bind: 'variables.serialNumber',
            search: true,
            overHidden: true,
          },
          {
            label: '流程分类',
            row: true,
            type: 'tree',
            dicUrl: '/blade-workflow/design/category/tree',
            props: {
              label: 'name',
              value: 'id',
            },
            prop: 'category',
            search: true,
          },
          {
            label: '申请人',
            prop: 'startUsername',
            search: true,
          },
          {
            label: '开始时间',
            prop: 'createTime',
            type: 'datetime',
            format: 'YYYY-MM-DD HH:mm',
            width: 165,
          },
          {
            label: '结束时间',
            prop: 'endTime',
            type: 'datetime',
            format: 'YYYY-MM-DD HH:mm',
            width: 165,
          },
          {
            label: '开始时间',
            prop: 'startTimeRange',
            type: 'datetime',
            dataType: 'string',
            format: 'YYYY-MM-DD HH:mm:ss',
            valueFormat: 'YYYY-MM-DD HH:mm:ss',
            hide: true,
            search: true,
            searchRange: true,
          },
          {
            label: '结束时间',
            prop: 'endTimeRange',
            type: 'datetime',
            dataType: 'string',
            format: 'YYYY-MM-DD HH:mm:ss',
            valueFormat: 'YYYY-MM-DD HH:mm:ss',
            hide: true,
            search: true,
            searchRange: true,
          },
          {
            label: '流程状态',
            prop: 'processIsFinished',
            dicData: [
              {
                label: '进行中',
                value: 'unfinished',
              },
              {
                label: '已完成',
                value: 'finished',
              },
              {
                label: '已终结',
                value: 'terminate',
              },
              {
                label: '已撤销',
                value: 'withdraw',
              },
              {
                label: '已撤回',
                value: 'recall',
              },
              {
                label: '被驳回',
                value: 'reject',
              },
              {
                label: '已删除',
                value: 'deleted',
              },
            ],
            type: 'select',
            search: true,
          },
          {
            label: '流转详情',
            prop: 'flow',
            overHidden: true,
          },
        ],
      },
      data: [],
      bpmnVisible: false,
      bpmnOption: {},
      detailVisible: false,
    };
  },
  computed: {
    ...mapGetters(['permission']),
    ids() {
      let ids = [];
      this.selectionList.forEach(ele => {
        ids.push(ele.processInstanceId);
      });
      return ids.join(',');
    },
  },
  methods: {
    handleDeleteProcess(row) {
      let processInstanceId;
      if (row && row.processInstanceId) {
        processInstanceId = row.processInstanceId;
      } else {
        if (this.selectionList.length === 0) {
          this.$message.warning('请选择至少一条数据');
          return;
        }
        processInstanceId = this.ids;
      }
      this.$confirm(
        '<p><span style="color: red;">逻辑删除</span>：进行中的流程直接结束，但会保留历史数据，标记为已删除。删除后无法恢复成进行中。<span style="color: #e6a23c;">已结束的流程无法逻辑删除。</span></p><p><span style="color: red;">物理删除</span>：完全删除所有数据，无法恢复。</p>',
        '警告',
        {
          confirmButtonText: '逻辑删除',
          cancelButtonText: '物理删除',
          type: 'warning',
          distinguishCancelAndClose: true,
          dangerouslyUseHTMLString: true,
        }
      )
        .then(() => {
          this.$prompt('请输入删除原因', '提示', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            inputPattern: /^[\s\S]*.*[^\s][\s\S]*$/,
            inputErrorMessage: '请输入删除原因',
          })
            .then(({ value }) => {
              deleteProcess({ processInstanceId, comment: value }).then(() => {
                this.$message.success('删除成功');
                this.onLoad(this.page, this.query);
              });
            })
            .catch(() => {});
        })
        .catch(action => {
          if (action == 'cancel') {
            this.$confirm('二次确认！此操作将永久删除流程数据且无法恢复！', '警告', {
              type: 'warning',
            })
              .then(() => {
                deleteProcess({ processInstanceId, status: 'force' }).then(() => {
                  this.$message.success('删除成功');
                  this.onLoad(this.page, this.query);
                });
              })
              .catch(() => {});
          }
        });
    },
    handleDetail(row) {
      this.dynamicRoute(row, 'detail', true).then(() => {
        this.form = { ...row };
        this.detailVisible = true;
      });
    },
    handleFlow(row) {
      const { taskId, processInstanceId } = row;
      detail({ taskId, processInsId: processInstanceId }).then(res => {
        const { process, flow } = res.data.data;

        this.bpmnOption = {
          mode: 'view',
          xml: process.xml,
          flows: this.handleResolveFlows(flow),
        };

        this.bpmnVisible = true;
      });
    },
    searchReset() {
      this.query = {};
      this.onLoad(this.page);
    },
    searchChange(params, done) {
      this.query = params;
      this.page.currentPage = 1;
      this.onLoad(this.page, params);
      done();
    },
    selectionChange(list) {
      this.selectionList = list;
    },
    currentChange(currentPage) {
      this.page.currentPage = currentPage;
    },
    sizeChange(pageSize) {
      this.page.pageSize = pageSize;
    },
    async onLoad(page, params = {}) {
      this.loading = true;
      getList(page.currentPage, page.pageSize, Object.assign(params, this.query))
        .then(res => {
          const data = res.data.data;
          this.page.total = data.total;
          this.data = data.records;
          this.loading = false;
        })
        .catch(() => {
          this.loading = false;
        });
    },
  },
};
</script>

<style lang="scss">
.nf-drawer {
  .el-drawer__body {
    padding: 0 20px;
    overflow: auto;
  }
}
</style>
